/* ====================================== toast  ====================================== */
import React from 'react'
import { Table } from 'antd'
import { VList } from 'virtuallist-antd'
import { Resizable } from 'react-resizable'
const { $Lazy, $fn } = window
// =====================================================================  Lazy
const Pagination 	= $Lazy.load(()=>import('@antd/pagination'))
const Empty 		= $Lazy.load(()=>import('@antd/empty'))
const SetHeaderModal= $Lazy.hook(()=>import('#private/pages/set-header-modal'), 1)
const MiniPagination= $Lazy.hook(()=>import('@tp/mini-pagination'))
// =====================================================================  列宽可拖拽
const ResizeableTitle = ({ onResize, width, ...restProps }) => {
	if (!width) { return <th {...restProps} /> }
	return (
		<Resizable width={width}  height={0} onResize={onResize} draggableOpts={{enableUserSelectHack: false}}
			handle={<span className='react-resizable-handle' onClick={e =>  e.stopPropagation()} />}
		>
			<th {...restProps} />
		</Resizable>
	)
}
// ===================================================================== 
let clear
// ===================================================================== 
const TableComponent = ({ 
	cols, data=[], type, loading, pag, onChange, onSizeChange, bordered, 
	className, size, expandedRowRender, expandRowByClick, onExpand, suffix, selfPag, onSelect, idStr='uuid',
	onSort, selectedKeys, selectedRows, rowSelect, onRowClass, onRow, flex, height, components, isDragWidth, isIndex,width='100%',
	hasTotal = true, hasBottom = true, children, split, simple, onMyRow, setHeader, disabled, onDisabled, onRows, checkedNoChange,onSelectAll, space='h10',
	hasCurrent = true, isInit, onMenu, noTotal
}, ref)=> {
	const [ col, setCol ] = React.useState(cols)
	const [ keys, setKeys ] = React.useState([])
	const [ rows, setRows ] = React.useState([])
	const [ result, setResult ] = React.useState([ ])
	const wrapRef = React.useRef()
	const p = { current:1, total:0, pageSize:10, ...pag}
	const hasPag = pag && data.length > 0 && p.total > window.$config.pageSize && hasBottom
	const [ component, setComponent ] = React.useState()
	const keyRef = React.useRef()
	const startRef = React.useRef(null)
	const endRef = React.useRef(null)
	
	idStr = idStr ? idStr : 'uuid'
	if(isIndex) idStr = 'index'
	
	// 伸缩列
	const handleResize = React.useCallback(index => (e, { size }) => {
		setCol(col => {
			const nextColumns = [...col];
			nextColumns[index] = { ...nextColumns[index], width: size.width }
			return nextColumns
		})
	},[])
	
	const setCols = React.useCallback((saveName)=>{
		if(setHeader){
			// 获取表头设置
			const name = saveName ? saveName : $fn.getPath()
			let _cols  = $fn.longSave([ name ])
				
			if($fn.hasArray(_cols)){
				let stack = []
				_cols.forEach(v=>{
					cols.forEach(p=>{
						if( v.dataIndex === p.dataIndex ){
							p.sorter = v.sorter
							p.width  = +v.width || p.width
							if(v.show){
								stack.push(p)
							}
						}
					})
				})
				setCol(stack)
			}else{
				setCol(cols)
			}
		}
	},[ cols, setHeader])
	
	React.useImperativeHandle( ref, () => {
		return {
			refreshCol : saveName => setCols(saveName),
			updateCol: cols => setCol(cols) // 更新表头 [2021-8-11 10:59:55 ?F10: AM?] --伍智睿
		}
	})
	
	React.useEffect(()=>{
		setCols()
	},[setCols])
	
	React.useEffect(()=>{
		// setResult( () => [] )
		// setTimeout(()=> setResult( () => $fn.hasArray(data) ? data : [] ) )
		setResult( () => $fn.hasArray(data) ? data : [] )
	},[data])
	
	// 7-12 伍智睿 优化
	const offsetHeight = height ? height : wrapRef.current?.offsetHeight
	const Vlist = React.useMemo(() => {
		return VList({height: offsetHeight })
	},[offsetHeight])
	
	React.useEffect(()=>{
		if(Array.isArray(selectedKeys)){
			setKeys(selectedKeys)
		}
		if(Array.isArray(selectedRows)){
			setRows(selectedRows)
		}
		
		const _component = components ? components : (data.length > 50  ? Vlist : {})
		
		if(isDragWidth){
			_component.header = {
				cell: ResizeableTitle
			}
			
			setCol(col => col.map((col, index) => ({
				...col,
				onHeaderCell: column => ({
					width: column.width,
					onResize: handleResize(index), 
					// style: { cursor: 'move' },
				})
			})))
		}
		
		setComponent(_component)
		
		if(type === 'checkbox'){
			window.focus()
			// 自定义多选
			window.addEventListener('keydown', e => {
				if(e.keyCode === 17){
					keyRef.current = true
					startRef.current = null
					endRef.current = null
				}
			})
			window.addEventListener('keyup', e => {
				keyRef.current = false
				startRef.current = null
				endRef.current = null
			})
		}
		
	}, [selectedKeys, selectedRows, data, type, isDragWidth, hasPag, components, height, handleResize, Vlist])
	
	const onCtrl = React.useCallback((bool,record, selectedRows) => {
		if(keyRef.current && type === 'checkbox'){
			if(bool){
				if(startRef.current !== null && startRef.current !== endRef.current){
					endRef.current  =  result.findIndex(v => v[idStr] === record[idStr] )
					
					const start = startRef.current
					const end = endRef.current
				
					const ctrlRows = result.filter((v,i)=> i >= start && i <= end )
					const _rows = $fn.onlyObject([ ...selectedRows, ...ctrlRows ], idStr)
					
					const _keys = _rows.map(v => v[idStr])
					
					setTimeout(()=> {
						setKeys(_keys)
						setRows(_rows)
						onSelect?.(_keys, _rows)
					}, 50)
					
				}else{
					startRef.current =  result.findIndex(v => v[idStr] === record[idStr] )
				}
			}
		}
	},[result, idStr, onSelect, type])
	
	return (
		<>
			<div ref={wrapRef} className={ `ex rel ${ isDragWidth ? 'table-resizable':'' } ${split?'split-table':''}` }>
				<Table 
					className 			= {`jzer-table abs_full ${className ? className : '' }` }
					style				= {{zIndex: loading ? 1 : 0}}
					bordered			= { bordered === false ? bordered : true }	
					rowKey				= { r =>  isIndex ?  r['index'] : r[idStr] }
					columns				= { col }
					dataSource			= { result }
					loading 			= { loading }
					scroll				= {{ y: true, x: width }}
					sticky				= { true }
					size				= { size ? size : 'small' }
					expandedRowRender 	= { expandedRowRender }
					expandRowByClick	= { expandRowByClick }
					onExpand			= { onExpand }
					components			= { component }
					onChange			= { (pagination, filters, sorter, extra) => {
						if(onSort){
							let type = null
							if(sorter.order === 'ascend'){	// 升序
								type = 1
							}else if(sorter.order === 'descend'){ // 降序
								type = 2
							}
							const param = type ? {sort:sorter.field, sort_type: type} : null
							onSort(param)
						}
					}}
					// 行事件
					onRow = { onMyRow ? onMyRow : (record, index)=>{
						return disabled ? null : {
							index,
							// 点击行
							onClick: e => {
								const className = e.target.className
								
								if(onDisabled){
									const d = onDisabled(record)
									if(d.disabled) return
								}
								
								if(rowSelect !== false && type ){
									const id = record[idStr]
									let _keys = []
									let _rows = []
									
									// 未选中时才能点击
									let checked = keys.includes(id)
									if(checked && checkedNoChange) {
										onRow?.(record, index)
										return
									}
									const isSplit = (className.indexOf('ant-table-selection-column') !== -1 || className.indexOf('ant-checkbox-wrapper') !== -1) && split 
									if($fn.isString(className) && isSplit){
										if( keys.indexOf(id) === -1 ){ // id 不存在，则添加
											_keys = [...keys, id ]
											_rows = [ ...rows, record ]
										}else{
											_keys = keys.filter(v => v !== id)
											_rows = rows.filter(v => v[idStr] !== id)
										}
										setKeys(_keys)
										setRows(_rows)
										onSelect?.(_keys, _rows)
										if(keyRef.current){onCtrl(!checked, record, _rows)}
										return;
									}
									
									if( type === 'checkbox'){ //  && !split
										if( keys.indexOf(id) === -1 ){ // id 不存在，则添加
											_keys = [...keys, id ]
											_rows = [ ...rows, record ]
										}else{
											_keys = keys.filter(v => v !== id)
											_rows = rows.filter(v => v[idStr] !== id)
										}
									}else{
										_keys = [ id ]
										_rows = [ record ]
									}
									
									setKeys(_keys)
									setRows(_rows)
									
									onSelect?.(_keys, _rows)
									onRow?.(record, index)
									// 选中时，才执行点击事件
									// if(!checked){ onRow?.(record, index) }
									
									//
									if(keyRef.current){
										onCtrl(!checked, record, _rows)
									}
								}else{
									onRow?.(record, index)
								}
								// 当前选中
								if(hasCurrent) {
									result.forEach((v,i)=>{ v.currentClass = null })
									if (result?.length && result[index]) {
										result[index].currentClass = 'click-active'
									}
								}
								if(!type){
									setResult([...data])
								}
							},
							// 双击行
							onDoubleClick: onRows ? e => {
								e.stopPropagation()
								// 未选中时才能点击
								onRows?.(record, index)
							} : null,
							onContextMenu: onMenu ? e => {
								e.stopPropagation()
								e.preventDefault()
								const id = record[idStr]
								if( keys.indexOf(id) === -1 ){ // id 不存在，则添加
									setKeys([id])
									setRows([record])
									onSelect?.([id], [record])
									onRow?.([record], index)
									onMenu?.(e, [record])
								}else{
									onSelect?.(keys, rows)
									onRow?.(rows, index)
									onMenu?.(e, rows)
								}
							}:null
						}
					} }
					rowClassName 		= { record => onRowClass ? onRowClass?.(record) : hasCurrent ? record.currentClass : '' }
					// 选择框配置
					rowSelection		= { type ? {
						type,
						fixed:true,
						selectedRowKeys: keys,
						onChange: (selectedRowKeys, selectedRows, index) => {
							let selectedKeys = selectedRowKeys
							if(idStr){
								selectedKeys = selectedRows.map(v => v[idStr])
							}
							
							setKeys(selectedKeys)
							onSelect?.(selectedKeys, selectedRows)
						},
						getCheckboxProps: onDisabled ? onDisabled : record => ({
							disabled
						}),
						onSelect: (record, selected, selectedRows, nativeEvent) => {
							// const selectedKeys = selectedRows.map(v => v[idStr])
							// setKeys(selectedKeys)
							// onSelect && onSelect(selectedKeys, selectedRows)
							
							onCtrl(selected, record, selectedRows)
							
							if(!split){
								if(checkedNoChange){
									onRow(record, selected)
								}else{
									selected && onRow?.(record)
								}
							}
						},
						// hideSelectAll:true,
						// 全选
						onSelectAll: (selected, selectedRows, changeRows)=>{
							onSelectAll?.(selectedRows, selected)
						}
					} : null}
					pagination			= { selfPag ? {
						// size: size,
						// current: p.current,
						// total: p.total,
						// pageSize: p.pageSize,
						// onChange: (current, pageSize) =>{ onChange?.(current, pageSize);},
						// showQuickJumper: true,
						// showSizeChanger: true,
						// hideOnSinglePage: !hasPag,
						// pageSizeOptions: [ 20, 50, 100, 150, 200, 500, 1000],
					} : false }
					indentSize			= {30}
				/>
				{/* 空数据 */}
				<Empty loading={loading} data={result} simple={simple} msg={ isInit === false ? '请按条件搜索数据' : '暂无数据' } />
			</div>
			{
				(result.length > 0 && hasBottom) ? <Pagination
					total		= { result.length }
					hasTotal	= { hasTotal }
					children	= { children }
					size		= 'small'
					pag			= { p }
					hasPag		= { hasPag }
					onChange	= { (current, pageSize) =>{ onChange?.(current, pageSize) } }
					suffix 	= { suffix }
				/> : null
			}
			{
				(result.length > 0 && noTotal) ? <MiniPagination onChange={(current, pageSize) => onChange?.(current, pageSize)} /> : null
			}
			{ result.length === 0 && <div className={space}></div>}
		</>
	)
}
const TableComponentRef = React.forwardRef(TableComponent)

class Index extends React.Component{
	state = {
		columns: this.props.cols
	}
	
	componentDidMount(){
		
	}
	
	componentWillUnmount(){
		clearTimeout(clear)
		this.setState = ()=>false
	}
	
	resize = () => {}
	
	openHeader = (cols, saveName) => {
		this.headerRef?.open?.(cols, saveName)
		this.saveName = saveName
	}
	
	refreshCol = saveName => this.table.refreshCol(saveName)
	
	data = () => this.props.data || []
	
	render(){
		const { wrapClassName, wrapStyle, simple, setHeader, height, cols, sort } = this.props
		return (
			<>
				<div onClick={e=>e.stopPropagation()} style={{minHeight:simple ? 130 : 208, height, ...wrapStyle}} className={ `${wrapClassName?wrapClassName:'xmlr'} ex rel fv bcf`}>
					<TableComponentRef ref={ref=>this.table=ref} {...this.props} cols={cols}/>
				</div>
				{/* 设置表头 */}
				{ setHeader && <SetHeaderModal sort={sort} onRefresh={()=>{ this.table.refreshCol(this.saveName) }} onRef={ ref => this.headerRef = ref } /> }
			</>
		)
	}
}

export default Index